package com.wencai.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.wencai.common.ResponseEnum;
import com.wencai.common.Result;
import com.wencai.common.StockConstant;
import com.wencai.service.WencaiService;
import io.netty.handler.codec.http.HttpRequest;
import lombok.extern.slf4j.Slf4j;
import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.core.har.*;
import net.lightbody.bmp.filters.RequestFilter;
import net.lightbody.bmp.proxy.CaptureType;
import net.lightbody.bmp.util.HttpMessageContents;
import net.lightbody.bmp.util.HttpMessageInfo;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;

import java.io.File;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class WencaiServiceImpl implements WencaiService {

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private RedisTemplate redisTemplate;
    @Value("${chrome.driver.path}")
    private String driverPpath;
    @Override
    public Result strategy(String strategy ,Integer num) {
        RLock lock = redissonClient.getLock("thsCookieLock");
        String cookie = "";
        try {
            //加锁
            boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
            if (!isLock) {
                log.info("没有获取到锁，重复请求了");
                return ResponseEnum.code_89004.result();
            }
            //获取问财数据
            return getWencaiData(strategy, cookie);
        } catch (Exception e) {
            log.error("问财数据解析异常:");
            if (num <= 3) {
                num++;
                //失效后重新获取cookie
                strategyDetailTHSJob();
                int count = 0;
                while (true) {
                    if (count >= 6) {
                        break;
                    }
                    count++;
                    if (StringUtils.isNotBlank(cookie)) {
                        try {
                            Thread.sleep(1000);
                            Object o = redisTemplate.opsForValue().get(StockConstant.THS_WENCAI);
                            if (ObjectUtil.isNull(o)) {
                                log.info("dfcf-wencai88888 is null");
                                break;
                            }
                            if (!o.toString().equals(cookie)) {
                                Result result = strategy(strategy, num);
                                return result;
                            }
                        } catch (Exception ex) {
                        }
                    }
                }
            }

        } finally {
            System.out.println("释放锁----------");
            //释放锁
            if (lock.isHeldByCurrentThread()) {
                lock.unlock(); // 安全释放
            }
        }
        return null;
    }



    public Result strategyDetailTHSJob() {
        WebDriver driver = null;
        try {
            BrowserMobProxy browserMobProxy = new BrowserMobProxyServer();
            driver = getWebDriver(browserMobProxy);
            // 监听网络请求
            browserMobProxy.addRequestFilter(new RequestFilter() {
                @Override
                public HttpResponse filterRequest(HttpRequest request, HttpMessageContents contents, HttpMessageInfo messageInfo) {
                    String requestUrl = request.getUri();
//                System.out.println("请求URL: " + requestUrl);
                    io.netty.handler.codec.http.HttpMethod method = request.getMethod();
                    String requestMethod = method.toString();
                    //同花顺获取查询数据的请求地址
                    // 获取请求头中的Cookie信息
                    if (requestUrl.contains("customized/chart/get-robot-data") && "POST".equals(requestMethod.toUpperCase())) {
                        try {
                            String cookieHeader = request.headers().get("Cookie");
                            if (cookieHeader != null) {
                                redisTemplate.opsForValue().set(StockConstant.THS_WENCAI, cookieHeader, 18, TimeUnit.HOURS);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    // 打印浏览器请求的URL和请求头
                    return null; // 继续处理请求
                }
            });
            // 打开链接
//        driver.get("https://xuangu.eastmoney.com/Result?q=%E6%98%A8%E6%97%A5%E6%B6%A8%E5%81%9C%EF%BC%8C%E6%8C%89%E7%85%A7%E6%B6%A8%E5%B9%85%E5%8F%96%E5%89%8D5%E5%8F%AA;");
            driver.get("https://www.iwencai.com/unifiedwap/result?w=昨日涨停，按照涨幅取前5只&querytype=stock&addSign=" + System.currentTimeMillis());
            getWebCookie(browserMobProxy, driver);
        } catch (Exception e) {
            log.error("同花顺问财异常：{}", e);
        } finally {
            if (ObjectUtil.isNotNull(driver)) {
                driver.quit();
            }
        }
        return null;
    }


    private WebDriver getWebDriver(BrowserMobProxy browserMobProxy) {
        browserMobProxy.start();
        browserMobProxy.enableHarCaptureTypes(CaptureType.REQUEST_CONTENT, CaptureType.RESPONSE_CONTENT);
        browserMobProxy.setHarCaptureTypes(CaptureType.RESPONSE_CONTENT);
        browserMobProxy.newHar("kk");

        Proxy seleniumProxy = ClientUtil.createSeleniumProxy(browserMobProxy);
        // 设置浏览器参数
        ChromeOptions options = new ChromeOptions();
        options.setProxy(seleniumProxy);
        options.setAcceptInsecureCerts(true);
        String[] ss = {"enable-automation"};
        options.setExperimentalOption("excludeSwitches", ss);
        options.addArguments("user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
                "--disable-blink-features=AutomationControlled");

//        if (chromeHeadless) {
            // 禁用沙箱
            options.addArguments("--no-sandbox");
            options.addArguments("--disable-dev-shm-usage");
            //浏览器后台运行
            options.addArguments("--headless");
//        }
        // 指定 ChromeDriver 的路径
        ChromeDriverService service = new ChromeDriverService.Builder()
                .usingDriverExecutable(new File(driverPpath))
                .usingAnyFreePort()
                .build();

        // 创建驱动对象
        return new ChromeDriver(service, options);
        // 创建驱动对象
//        return new ChromeDriver(options);
    }


    private void getWebCookie(BrowserMobProxy browserMobProxy, WebDriver driver) {
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        // 获得 Cookie
        Set<Cookie> cookies = driver.manage().getCookies();
        // 设置WebDriver路径，确保与您的浏览器驱动程序路径一致
        log.info("cookies========:{}", cookies);
        try {
            // 找到登录按钮并点击
            Thread.sleep(500);
            //3日涨幅>10%，且5日涨跌幅>20%，且上市时间>1年，且换手率>=10%;
            driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
            // 获取返回的请求内容
            Har har = browserMobProxy.getHar();
            List<HarEntry> entries = har.getLog().getEntries();
            for (HarEntry harEntry : entries) {
                HarResponse response = harEntry.getResponse();
                HarRequest request = harEntry.getRequest();
                String url = harEntry.getRequest().getUrl();
                List<HarNameValuePair> headers = request.getHeaders();
                if (request.getUrl().contains("pw/search-code")) {
                    System.out.println("body:" + request.getPostData());
                    System.out.println("getQueryString:" + request.getQueryString());
                }
                for (HarNameValuePair harp : headers) {
                    System.out.println(harp.toString());
                }
            }
            Thread.sleep(2000);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            // 关闭浏览器
            driver.quit();
        }
    }


    public Result getWencaiData(String strategy, String cookie) {
        Result res = new Result();
        int hour = LocalDateTime.now().getHour();
        int minute = LocalDateTime.now().getMinute();
        if (hour < 9) {
            return ResponseEnum.code_89003.result();
        }
        if (hour <= 9 && minute < 26) {
            return ResponseEnum.code_89003.result();
        }
        Object o = redisTemplate.opsForValue().get(StockConstant.THS_WENCAI);
        if (ObjectUtil.isNull(o)) {
            log.info("dfcf-wencai is null");
            strategyDetailTHSJob();
            return null;
        }
        cookie = o.toString();
        // 设置请求头
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Cookie", cookie);
        headers.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36");
        // 构建请求体
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("queryArea", "");
        requestBody.put("perpage", 50);
        requestBody.put("question", strategy);
        requestBody.put("secondaryIntent", "stock");
        requestBody.put("rsh", "Ths_iwencai_Xuangu_6wdtdtm5fvfdpb1wm17oz4w2zhs52esx");
        requestBody.put("blockList", "");
        requestBody.put("addInfo", "{\"urp\":{\"scene\":1,\"company\":1,\"business\":1},\"contentType\":\"json\",\"searchInfo\":true}");
        requestBody.put("logInfo", "{\"input_type\":\"typewrite\"}");
        requestBody.put("page", 1);
        requestBody.put("source", "Ths_iwencai_Xuangu");
        requestBody.put("version", "2.0");

        // 创建 HttpEntity 对象
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);

        // 发送 POST 请求
        String url = "https://www.iwencai.com/customized/chart/get-robot-data";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
        // 输出响应体
        Map resMap = JSON.parseObject(response.getBody(), Map.class);
        if (ObjectUtil.isEmpty(resMap)) {
            log.warn("resMap is null:{}", resMap);
            return null;
        }
        Object data = resMap.get("data");
        Map<String, Object> dataMap = (Map<String, Object>) data;
        Object result = dataMap.get("answer");

        List<Map<String, Object>> answer = (List<Map<String, Object>>) result;
        Map<String, Object> map = answer.get(0);
        Object txt = map.get("txt");
        List<Map<String, Object>> txtList = (List<Map<String, Object>>) txt;
        Map<String, Object> txtMap = txtList.get(0);
        Object content = txtMap.get("content");
        Map<String, Object> contentMap = null;
        if (content instanceof String) {
            contentMap = JSON.parseObject(content.toString(), Map.class);
        } else {
            contentMap = (Map<String, Object>) content;
        }
        Object components = contentMap.get("components");
        List<Map<String, Object>> componentsList = (List<Map<String, Object>>) components;
        Map<String, Object> componentsMap = null;
        if (content instanceof String && componentsList.size() == 1) {
            componentsMap = componentsList.get(0);
        } else if (content instanceof String && componentsList.size() > 1) {
            componentsMap = componentsList.get(1);
        } else {
            componentsMap = componentsList.get(2);
        }
        Object data1 = componentsMap.get("data");
        Map<String, Object> dataMap1 = (Map<String, Object>) data1;
        Object datas = dataMap1.get("datas");
        List<Map<String, Object>> datasList = (List<Map<String, Object>>) datas;
        return res.setData(datasList);
    }

}
